home *** CD-ROM | disk | FTP | other *** search
/ Chip 2007 January, February, March & April / Chip-Cover-CD-2007-02.iso / Pakiet internetowy / Przegladarki internetowe / Mozilla Seamonkey 1.0.5 pl / seamonkey-1.0.5.pl-PL.win32.installer.exe / MAIL.XPI / bin / chrome / messenger.jar / content / messenger / messengerdnd.js < prev    next >
Encoding:
JavaScript  |  2005-03-22  |  16.7 KB  |  465 lines

  1. /* -*- Mode: Java; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
  2. /* ***** BEGIN LICENSE BLOCK *****
  3.  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
  4.  *
  5.  * The contents of this file are subject to the Mozilla Public License Version
  6.  * 1.1 (the "License"); you may not use this file except in compliance with
  7.  * the License. You may obtain a copy of the License at
  8.  * http://www.mozilla.org/MPL/
  9.  *
  10.  * Software distributed under the License is distributed on an "AS IS" basis,
  11.  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
  12.  * for the specific language governing rights and limitations under the
  13.  * License.
  14.  *
  15.  * The Original Code is mozilla.org code.
  16.  *
  17.  * The Initial Developer of the Original Code is
  18.  * Netscape Communications Corporation.
  19.  * Portions created by the Initial Developer are Copyright (C) 1998
  20.  * the Initial Developer. All Rights Reserved.
  21.  *
  22.  * Contributor(s):
  23.  *   disttsc@bart.nl
  24.  *   jarrod.k.gray@rose-hulman.edu
  25.  *   Jan Varga <varga@ku.sk>
  26.  *
  27.  * Alternatively, the contents of this file may be used under the terms of
  28.  * either of the GNU General Public License Version 2 or later (the "GPL"),
  29.  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
  30.  * in which case the provisions of the GPL or the LGPL are applicable instead
  31.  * of those above. If you wish to allow use of your version of this file only
  32.  * under the terms of either the GPL or the LGPL, and not to allow others to
  33.  * use your version of this file under the terms of the MPL, indicate your
  34.  * decision by deleting the provisions above and replace them with the notice
  35.  * and other provisions required by the GPL or the LGPL. If you do not delete
  36.  * the provisions above, a recipient may use your version of this file under
  37.  * the terms of any one of the MPL, the GPL or the LGPL.
  38.  *
  39.  * ***** END LICENSE BLOCK ***** */
  40.  
  41. // cache these services
  42. var RDF = Components.classes["@mozilla.org/rdf/rdf-service;1"].getService().QueryInterface(Components.interfaces.nsIRDFService);
  43. var dragService = Components.classes["@mozilla.org/widget/dragservice;1"].getService().QueryInterface(Components.interfaces.nsIDragService);
  44. var nsIDragService = Components.interfaces.nsIDragService;
  45.  
  46. function debugDump(msg)
  47. {
  48.   // uncomment for noise
  49.   // dump(msg+"\n");
  50. }
  51.  
  52. function CanDropOnFolderTree(index, orientation)
  53. {
  54.     if (orientation != Components.interfaces.nsITreeView.DROP_ON)
  55.         return false;
  56.  
  57.     var dragSession = null;
  58.     var dragFolder = false;
  59.  
  60.     dragSession = dragService.getCurrentSession();
  61.     if (! dragSession)
  62.         return false;
  63.  
  64.     var flavorSupported = dragSession.isDataFlavorSupported("text/x-moz-message") || dragSession.isDataFlavorSupported("text/x-moz-folder");
  65.  
  66.     var trans = Components.classes["@mozilla.org/widget/transferable;1"].createInstance(Components.interfaces.nsITransferable);
  67.     if (! trans)
  68.         return false;
  69.  
  70.     trans.addDataFlavor("text/x-moz-message");
  71.     trans.addDataFlavor("text/x-moz-folder");
  72.     trans.addDataFlavor("text/x-moz-url");
  73.  
  74.     var folderTree = GetFolderTree();
  75.     var targetResource = GetFolderResource(folderTree, index);
  76.     var targetUri = targetResource.Value;
  77.     var targetFolder = targetResource.QueryInterface(Components.interfaces.nsIMsgFolder);
  78.     var targetServer = targetFolder.server;
  79.     var sourceServer;
  80.     var sourceResource;
  81.    
  82.     for (var i = 0; i < dragSession.numDropItems; i++)
  83.     {
  84.         dragSession.getData (trans, i);
  85.         var dataObj = new Object();
  86.         var dataFlavor = new Object();
  87.         var len = new Object();
  88.         try
  89.         {
  90.             trans.getAnyTransferData (dataFlavor, dataObj, len );
  91.         }
  92.         catch (ex)
  93.         {
  94.             continue;   //no data so continue;
  95.         }
  96.         if (dataObj)
  97.             dataObj = dataObj.value.QueryInterface(Components.interfaces.nsISupportsString);
  98.         if (! dataObj)
  99.             continue;
  100.  
  101.         // pull the URL out of the data object
  102.         var sourceUri = dataObj.data.substring(0, len.value);
  103.         if (! sourceUri)
  104.             continue;
  105.         if (dataFlavor.value == "text/x-moz-message")
  106.         {
  107.             sourceResource = null;
  108.             var isServer = GetFolderAttribute(folderTree, targetResource, "IsServer");
  109.             if (isServer == "true")
  110.             {
  111.                 debugDump("***isServer == true\n");
  112.                 return false;
  113.             }
  114.             // canFileMessages checks no select, and acl, for imap.
  115.             var canFileMessages = GetFolderAttribute(folderTree, targetResource, "CanFileMessages");
  116.             if (canFileMessages != "true")
  117.             {
  118.                 debugDump("***canFileMessages == false\n");
  119.                 return false;
  120.             }
  121.             var hdr = messenger.messageServiceFromURI(sourceUri).messageURIToMsgHdr(sourceUri);
  122.             if (hdr.folder == targetFolder)
  123.                 return false;
  124.             break;
  125.         } else if (dataFlavor.value == "text/x-moz-folder") {
  126.  
  127.           // we should only get here if we are dragging and dropping folders
  128.           dragFolder = true;
  129.           sourceResource = RDF.GetResource(sourceUri);
  130.           var sourceFolder = sourceResource.QueryInterface(Components.interfaces.nsIMsgFolder);
  131.           sourceServer = sourceFolder.server;
  132.  
  133.           if (targetUri == sourceUri)    
  134.               return false;
  135.  
  136.           //don't allow immediate child to be dropped to it's parent
  137.           if (targetFolder.URI == sourceFolder.parent.URI)
  138.           {
  139.               debugDump(targetFolder.URI + "\n");
  140.               debugDump(sourceFolder.parent.URI + "\n");     
  141.               return false;
  142.           }
  143.           
  144.           // don't allow dragging of virtual folders across accounts
  145.           if ((sourceFolder.flags & MSG_FOLDER_FLAG_VIRTUAL) && sourceServer != targetServer)
  146.             return false;
  147.  
  148.           var isAncestor = sourceFolder.isAncestorOf(targetFolder);
  149.           // don't allow parent to be dropped on its ancestors
  150.           if (isAncestor)
  151.               return false;
  152.         } else if (dataFlavor.value == "text/x-moz-url") {
  153.           // eventually check to make sure this is an http url before doing anything else...
  154.           var uri = Components.classes["@mozilla.org/network/standard-url;1"].
  155.                       createInstance(Components.interfaces.nsIURI);
  156.           var url = sourceUri.split("\n")[0];
  157.           uri.spec = url;
  158.  
  159.           if ( (uri.schemeIs("http") || uri.schemeIs("https")) && targetServer && targetServer.type == 'rss')
  160.             return true;
  161.         }
  162.     }
  163.  
  164.     if (dragFolder)
  165.     {
  166.         //first check these conditions then proceed further
  167.         debugDump("***isFolderFlavor == true \n");
  168.  
  169.         // no copy for folder drag within a server
  170.         if (dragSession.dragAction == nsIDragService.DRAGDROP_ACTION_COPY && sourceServer == targetServer)
  171.             return false;
  172.  
  173.         var canCreateSubfolders = GetFolderAttribute(folderTree, targetResource, "CanCreateSubfolders");
  174.         // if cannot create subfolders then a folder cannot be dropped here     
  175.         if (canCreateSubfolders == "false")
  176.         {
  177.             debugDump("***canCreateSubfolders == false \n");
  178.             return false;
  179.         }
  180.  
  181.         var serverType = GetFolderAttribute(folderTree, targetResource, "ServerType");
  182.  
  183.         // if we've got a folder that can't be renamed
  184.         // allow us to drop it if we plan on dropping it on "Local Folders"
  185.         // (but not within the same server, to prevent renaming folders on "Local Folders" that
  186.         // should not be renamed)
  187.         var srcCanRename = GetFolderAttribute(folderTree, sourceResource, "CanRename");
  188.         if (srcCanRename == "false") {
  189.             if (sourceServer == targetServer)
  190.                 return false;
  191.             if (serverType != "none")
  192.                 return false;
  193.         }
  194.     }
  195.  
  196.     //message or folder
  197.     if (flavorSupported)
  198.     {
  199.         dragSession.canDrop = true;
  200.         return true;
  201.     }
  202.     
  203.     return false;
  204. }
  205.  
  206. function DropOnFolderTree(row, orientation)
  207. {
  208.     if (orientation != Components.interfaces.nsITreeView.DROP_ON)
  209.         return false;
  210.  
  211.     var folderTree = GetFolderTree();
  212.     var targetResource = GetFolderResource(folderTree, row);
  213.     var targetFolder = targetResource.QueryInterface(Components.interfaces.nsIMsgFolder);
  214.     var targetServer = targetFolder.server;
  215.  
  216.     var targetUri = targetResource.Value;
  217.     debugDump("***targetUri = " + targetUri + "\n");
  218.  
  219.     var dragSession = dragService.getCurrentSession();
  220.     if (! dragSession )
  221.         return false;
  222.  
  223.     var trans = Components.classes["@mozilla.org/widget/transferable;1"].createInstance(Components.interfaces.nsITransferable);
  224.     trans.addDataFlavor("text/x-moz-message");
  225.     trans.addDataFlavor("text/x-moz-folder");
  226.     trans.addDataFlavor("text/x-moz-url");
  227.  
  228.     var list = Components.classes["@mozilla.org/supports-array;1"].createInstance(Components.interfaces.nsISupportsArray);
  229.  
  230.     var dropMessage;
  231.     var sourceUri;
  232.     var sourceResource;
  233.     var sourceFolder;
  234.     var sourceServer;
  235.     
  236.     for (var i = 0; i < dragSession.numDropItems; i++)
  237.     {
  238.         dragSession.getData (trans, i);
  239.         var dataObj = new Object();
  240.         var flavor = new Object();
  241.         var len = new Object();
  242.         trans.getAnyTransferData(flavor, dataObj, len);
  243.         if (dataObj)
  244.             dataObj = dataObj.value.QueryInterface(Components.interfaces.nsISupportsString);
  245.         if (! dataObj)
  246.             continue;
  247.  
  248.         // pull the URL out of the data object
  249.         sourceUri = dataObj.data.substring(0, len.value);
  250.         if (! sourceUri)
  251.             continue;
  252.  
  253.         debugDump("    Node #" + i + ": drop " + sourceUri + " to " + targetUri + "\n");
  254.         
  255.         // only do this for the first object, either they are all messages or they are all folders
  256.         if (i == 0) 
  257.         {
  258.           if (flavor.value == "text/x-moz-folder") 
  259.           {
  260.             sourceResource = RDF.GetResource(sourceUri);
  261.             sourceFolder = sourceResource.QueryInterface(Components.interfaces.nsIMsgFolder);
  262.             dropMessage = false;  // we are dropping a folder
  263.           }
  264.           else if (flavor.value == "text/x-moz-message")
  265.             dropMessage = true;
  266.           else if (flavor.value == "text/x-moz-url")
  267.           {
  268.             var uri = Components.classes["@mozilla.org/network/standard-url;1"].
  269.                         createInstance(Components.interfaces.nsIURI);
  270.             var url = sourceUri.split("\n")[0];
  271.             uri.spec = url;
  272.             
  273.             if ( (uri.schemeIs("http") || uri.schemeIs("https")) && targetServer && targetServer.type == 'rss')
  274.             {
  275.               var rssService = Components.classes["@mozilla.org/newsblog-feed-downloader;1"].getService().
  276.                                QueryInterface(Components.interfaces.nsINewsBlogFeedDownloader);
  277.               if (rssService)
  278.                 rssService.subscribeToFeed(url, targetFolder, msgWindow);
  279.               return true;
  280.             }
  281.             else 
  282.               return false;            
  283.           }
  284.         }
  285.         else {
  286.            if (!dropMessage)
  287.              dump("drag and drop of multiple folders isn't supported\n");
  288.         }
  289.  
  290.         if (dropMessage) {
  291.             // from the message uri, get the appropriate messenger service
  292.             // and then from that service, get the msgDbHdr
  293.             list.AppendElement(messenger.messageServiceFromURI(sourceUri).messageURIToMsgHdr(sourceUri));
  294.         }
  295.         else {
  296.             // Prevent dropping of a node before, after, or on itself
  297.             if (sourceResource == targetResource)    
  298.                 continue;
  299.  
  300.             list.AppendElement(sourceResource);
  301.         }
  302.     }
  303.  
  304.     if (list.Count() < 1)
  305.        return false;
  306.  
  307.     var isSourceNews = false;
  308.     isSourceNews = isNewsURI(sourceUri);
  309.  
  310.     if (dropMessage) {
  311.         var sourceMsgHdr = list.GetElementAt(0).QueryInterface(Components.interfaces.nsIMsgDBHdr);
  312.         sourceFolder = sourceMsgHdr.folder;
  313.         sourceResource = sourceFolder.QueryInterface(Components.interfaces.nsIRDFResource);
  314.         sourceServer = sourceFolder.server;
  315.  
  316.         try {
  317.             if (isSourceNews) {
  318.                 // news to pop or imap is always a copy
  319.                 messenger.CopyMessages(GetFolderDatasource(), sourceResource, targetResource, list, false);
  320.             }
  321.             else {
  322.                 var dragAction = dragSession.dragAction;
  323.                 if (dragAction == nsIDragService.DRAGDROP_ACTION_COPY)
  324.                     messenger.CopyMessages(GetFolderDatasource(), sourceResource, targetResource, list, false);
  325.                 else if (dragAction == nsIDragService.DRAGDROP_ACTION_MOVE)
  326.                     messenger.CopyMessages(GetFolderDatasource(), sourceResource, targetResource, list, true);
  327.             }
  328.         }
  329.         catch (ex) {
  330.             dump("failed to copy messages: " + ex + "\n");
  331.         }
  332.     }
  333.     else {
  334.         sourceServer = sourceFolder.server;
  335.         try 
  336.         {
  337.             messenger.CopyFolders(GetFolderDatasource(), targetResource, list, (sourceServer == targetServer));
  338.         }
  339.         catch(ex)
  340.         {
  341.             dump ("Exception : CopyFolders " + ex + "\n");
  342.         }
  343.     }
  344.     return true;
  345. }
  346.  
  347. function BeginDragFolderTree(event)
  348. {
  349.     debugDump("BeginDragFolderTree\n");
  350.  
  351.     if (event.originalTarget.localName != "treechildren")
  352.       return false;
  353.  
  354.     var folderTree = GetFolderTree();
  355.     var row = folderTree.treeBoxObject.getRowAt(event.clientX, event.clientY);
  356.     if (row == -1)
  357.       return false;
  358.  
  359.     var folderResource = GetFolderResource(folderTree, row);
  360.  
  361.     if (GetFolderAttribute(folderTree, folderResource, "IsServer") == "true")
  362.     {
  363.       debugDump("***IsServer == true\n");
  364.       return false;
  365.     }
  366.  
  367.     // do not allow the drag when news is the source
  368.     if (GetFolderAttribute(folderTree, folderResource, "ServerType") == "nntp") 
  369.     {
  370.       debugDump("***ServerType == nntp\n");
  371.       return false;
  372.     }
  373.  
  374.     var selectedFolders = GetSelectedFolders();
  375.     return BeginDragTree(event, folderTree, selectedFolders, "text/x-moz-folder");
  376. }
  377.  
  378. function BeginDragThreadPane(event)
  379. {
  380.     debugDump("BeginDragThreadPane\n");
  381.  
  382.     var threadTree = GetThreadTree();
  383.     var selectedMessages = GetSelectedMessages();
  384.     if (!selectedMessages)
  385.       return false;
  386.  
  387.     //A message can be dragged from one window and dropped on another window
  388.     //therefore setNextMessageAfterDelete() here 
  389.     //no major disadvantage even if it is a copy operation
  390.  
  391.     SetNextMessageAfterDelete();
  392.     return BeginDragTree(event, threadTree, selectedMessages, "text/x-moz-message");
  393. }
  394.  
  395. function BeginDragTree(event, tree, selArray, flavor)
  396. {
  397.     var dragStarted = false;
  398.  
  399.     var transArray = Components.classes["@mozilla.org/supports-array;1"].createInstance(Components.interfaces.nsISupportsArray);
  400.     if ( !transArray ) 
  401.       return false;
  402.  
  403.     // let's build the drag region
  404.     var region = null;
  405.     try {
  406.       region = Components.classes["@mozilla.org/gfx/region;1"].createInstance(Components.interfaces.nsIScriptableRegion);
  407.       region.init();
  408.       var obo = tree.treeBoxObject;
  409.       var bo = obo.treeBody.boxObject;
  410.       var sel= tree.view.selection;
  411.  
  412.       var rowX = bo.x;
  413.       var rowY = bo.y;
  414.       var rowHeight = obo.rowHeight;
  415.       var rowWidth = bo.width;
  416.  
  417.       //add a rectangle for each visible selected row
  418.       for (var i = obo.getFirstVisibleRow(); i <= obo.getLastVisibleRow(); i ++)
  419.       {
  420.         if (sel.isSelected(i))
  421.           region.unionRect(rowX, rowY, rowWidth, rowHeight);
  422.         rowY = rowY + rowHeight;
  423.       }
  424.       
  425.       //and finally, clip the result to be sure we don't spill over...
  426.       if(!region.isEmpty())
  427.         region.intersectRect(bo.x, bo.y, bo.width, bo.height);
  428.     } catch(ex) {
  429.       dump("Error while building selection region: " + ex + "\n");
  430.       region = null;
  431.     }
  432.     
  433.     var count = selArray.length;
  434.     debugDump("selArray.length = " + count + "\n");
  435.     for (i = 0; i < count; ++i ) {
  436.         var trans = Components.classes["@mozilla.org/widget/transferable;1"].createInstance(Components.interfaces.nsITransferable);
  437.         if (!trans) 
  438.           return false;
  439.  
  440.         var genTextData = Components.classes["@mozilla.org/supports-string;1"].createInstance(Components.interfaces.nsISupportsString);
  441.         if (!genTextData) 
  442.           return false;
  443.  
  444.         trans.addDataFlavor(flavor);
  445.  
  446.         // get id (url)
  447.         var id = selArray[i];
  448.         genTextData.data = id;
  449.         debugDump("    ID #" + i + " = " + id + "\n");
  450.  
  451.         trans.setTransferData ( flavor, genTextData, id.length * 2 );  // doublebyte byte data
  452.  
  453.         // put it into the transferable as an |nsISupports|
  454.         var genTrans = trans.QueryInterface(Components.interfaces.nsISupports);
  455.         transArray.AppendElement(genTrans);
  456.     }
  457.  
  458.     dragService.invokeDragSession ( event.target, transArray, region, nsIDragService.DRAGDROP_ACTION_COPY +
  459.     nsIDragService.DRAGDROP_ACTION_MOVE );
  460.  
  461.     dragStarted = true;
  462.  
  463.     return(!dragStarted);  // don't propagate the event if a drag has begun
  464. }
  465.